package com.wdciti.sccp.iot.tsdata.impl.iotdb;

import com.wdciti.sccp.iot.tsdata.core.api.TSDBWrapper;
import com.wdciti.sccp.iot.tsdata.core.api.TsDataException;
import org.apache.iotdb.rpc.IoTDBConnectionException;
import org.apache.iotdb.rpc.StatementExecutionException;
import org.apache.iotdb.session.pool.SessionPool;

/**
 * @author JINWEN
 */
public class IotdbWrapper implements TSDBWrapper<SessionPool> {

    private final SessionPool sessionPool;

    public IotdbWrapper(SessionPool sessionPool) {
        this.sessionPool = sessionPool;
    }

    @Override
    public IotdbWrapper open() throws TsDataException {
        return this;
    }

    @Override
    public void close() {
        sessionPool.close();
    }

    @Override
    public SessionPool getSessionWrapper() {
        return this.sessionPool;
    }

//    public SessionDataSetWrapper executeQueryStatement(String tsSql) throws TsDataException {
//        return this.executeQueryStatement(tsSql, 2000);
//    }
//
//    public SessionDataSetWrapper executeQueryStatement(String tsSql, int timeOutInMs) throws TsDataException {
//        try {
//            return sessionPool.executeQueryStatement(tsSql, timeOutInMs);
//        } catch (IoTDBConnectionException | StatementExecutionException e) {
//            throw new TsDataException(e);
//        } finally {
//            sessionPool.close();
//        }
//    }

    public IotDbSessionConfig getSessionConfig() {
        IotDbSessionConfig config = new IotDbSessionConfig();
        config.setHost(sessionPool.getHost());
        config.setPort(sessionPool.getPort());
        config.setUsername(sessionPool.getUser());
        config.setPassword(sessionPool.getPassword());
        config.setMaxSize(sessionPool.getMaxSize());
        return config;
    }


//    public void useDatabase(String path) throws TsDataException {
//        try {
//            sessionPool.createDatabase(path);
//        } catch (IoTDBConnectionException | StatementExecutionException e) {
//            throw new TsDataException(e.getMessage(), e.getCause());
//        }
//    }

//    public void saveTemplate(Template template) {
//        Map<String, Measurement> map = template.getMeasurements();
//        List<String> keys = new ArrayList<>();
//        List<TSDataType> dataTypes = new ArrayList<>();
//        List<TSEncoding> encodings = new ArrayList<>();
//        List<CompressionType> compressors = new ArrayList<>();
//        boolean aligned = template.isAligned();
//        for (Measurement measurement : map.values()) {
//            dataTypes.add(TsDataUtils.getTsDataType(measurement.getType()));
//            encodings.add(TSEncoding.PLAIN); //先不编码
//            compressors.add(CompressionType.SNAPPY);  //统一压缩方式
//        }
//        try {
//            session.createSchemaTemplate(template.getName(), keys, dataTypes, encodings, compressors, aligned);
//        } catch (IOException | StatementExecutionException | IoTDBConnectionException e) {
//            throw new TsDataException(e.getMessage(), e.getCause());
//        }
//    }
//
//    public void deleteTemplate(String templateName) throws TsDataException {
//        try {
//            session.dropSchemaTemplate(templateName);
//        } catch (IoTDBConnectionException | StatementExecutionException e) {
//            throw new TsDataException(e.getMessage(), e.getCause());
//        }
//    }
//
//    public List<String> showTemplate(String templateName) {
//        try {
//            return session.showPathsTemplateUsingOn(templateName);
//        } catch (StatementExecutionException | IoTDBConnectionException e) {
//            throw new TsDataException(e.getMessage(), e.getCause());
//        }
//    }
//
//    public void insertDataPointToSeries(DataPoint dataPoint) {
//
//        List<String> keys = new ArrayList<>();
//        List<Object> values = new ArrayList<>();
//        List<TSDataType> types = new ArrayList<>();
//        Map<String, Object> pairs = dataPoint.getDataPair();
//        Map<String, Measurement> maps = dataPoint.getTemplate().getMeasurements();
//        pairs.forEach((k, v) -> {
//            keys.add(k);
//            types.add(TsDataUtils.getTsDataType(maps.get(k).getType()));
//            values.add(v);
//        });
//        try {
//            boolean isAligned = dataPoint.getTemplate().isAligned();
//            if (isAligned) {
//                session.insertAlignedRecord(dataPoint.getPath(), dataPoint.getTimestamp(), keys, types, values);
//            } else {
//                session.insertRecord(dataPoint.getPath(), dataPoint.getTimestamp(), keys, types, values);
//            }
//        } catch (IoTDBConnectionException | StatementExecutionException e) {
//            throw new TsDataException(e.getMessage(), e.getCause());
//        }
//    }
//
//    public void insertRawDataIntoSeries(String path, Template template, Long[] timestamps, String[] measurements, Object[][] values, boolean isAligned) {
//        Map<String, Measurement> map = template.getMeasurements();
//        List<String> ls = Arrays.asList(measurements);
//        List<List<String>> lls = new ArrayList<>();
//        List<List<TSDataType>> llt = new ArrayList<>();
//        for (int i = 0; i < timestamps.length; i++) {
//            lls.add(ls);
//            List<TSDataType> lt = new ArrayList<>();
//            for (String s : measurements) {
//                lt.add(TsDataUtils.getTsDataType(map.get(s).getType()));
//            }
//            llt.add(lt);
//        }
//
//        try {
//            if (isAligned) {
//                session.insertAlignedRecordsOfOneDevice(path, Arrays.asList(timestamps), lls, llt, TsDataUtils.asList(values));
//            } else {
//                session.insertRecordsOfOneDevice(path, Arrays.asList(timestamps), lls, llt, TsDataUtils.asList(values));
//            }
//        } catch (IoTDBConnectionException | StatementExecutionException e) {
//            throw new TsDataException(e.getMessage(), e.getCause());
//        }
//    }
//
//    public TsDataResult selectRowData(List<String> paths, long startTime, long endTime) throws TsDataException {
//        try {
//            SessionDataSet set = session.executeRawDataQuery(paths, startTime, endTime, 10000);
//            List<String> columnNames = set.getColumnNames();
//            TsDataResult tsDataResult = new TsDataResult();
//            for (int i = 1; i < columnNames.size(); i++) { //first column is Time
//                String path = columnNames.get(i);
//                DataType type = DataType.valueOf(set.getColumnTypes().get(i));
//                Series series = new Series(path, type);
//                tsDataResult.addSeries(series);
//            }
//            while (set.hasNext()) {
//                RowRecord record = set.next();
//                List<Field> fields = record.getFields();
//                for (int i = 0; i < fields.size(); i++) {
//                    Field field = fields.get(i);
//                    Series series = tsDataResult.getPathSeries().get(columnNames.get(i + 1));
//                    Object value = field.getObjectValue(TsDataUtils.getTsDataType(series.getDataType()));
//                    series.putTsValue(record.getTimestamp(), value);
//                }
//            }
//            return tsDataResult;
//        } catch (StatementExecutionException | IoTDBConnectionException e) {
//            throw new TsDataException(e.getMessage(), e.getCause());
//        }
//    }

}
